namespace NetFx.SMIL
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Reflection;
  using System.Reflection.Emit;

  using NetFx.AGIL;
  public class OperationFormat
  {
    #region Statics
    public static OperationFormat of(int length)
    {
      return new OperationFormat(length);
    }
    public static OperationFormat of(int branchingTo, int shortFormat, int longFormat)
    {
      return new OperationFormat(branchingTo, shortFormat, longFormat);
    }
    #endregion
    #region Fields
    protected bool isBranching = false;
    protected int branchingTo = 0;
    protected int shortFormat = 0;
    protected int longFormat = 0;
    protected bool? isLongFormat = null;
    #endregion
    #region Properties
    public virtual bool IsPranching
    {
      get
      {
        return isBranching;
      }
    }
    public virtual int BranchingTo
    {
      get
      {
        return this.branchingTo;
      }
    }
    public virtual int ShortFormat
    {
      get
      {
        return this.shortFormat;
      }
    }
    public virtual int LongFormat
    {
      get
      {
        return this.longFormat;
      }
    }
    public virtual bool? IsLongFormat
    {
      get
      {
        return this.isLongFormat;
      }
      set
      {
        this.isLongFormat = value;
      }
    }
    #endregion
    #region Constructors
    public OperationFormat(int length)
    {
      this.isBranching = false;
      this.shortFormat = this.longFormat = length;
      this.branchingTo = int.MaxValue;
    }
    public OperationFormat(int branchingTo, int shortFormat, int longFormat)
    {
      this.isBranching = true;
      this.branchingTo = branchingTo;
      this.shortFormat = shortFormat;
      this.longFormat = longFormat;
    }
    #endregion
    #region Methods
    #endregion
  }

  public class OperationFormatResolver:IDisposable  
  {
    #region Statics
    public static OperationFormatResolver it()
    {
      return new OperationFormatResolver();
    }
    #endregion
    #region Fields
    protected List<OperationFormat> formatList = null;
    protected int currentOperationIndex = 0;
    protected bool isDisposed = false;
    #endregion
    #region Prroperties
    public virtual List<OperationFormat> FormatList
    {
      get
      {
        return this.formatList == null ?
          this.formatList = new List<OperationFormat>() :
          this.formatList;
      }
    }
    public virtual bool IsDisposed
    {
      get
      {
        return this.isDisposed;
      }
    }
    #endregion
    #region Constructors
    public OperationFormatResolver()
    {
    }
    #endregion
    #region Methods
    public virtual void Resolve(List<SmilOperation> operations)
    {
      if (operations != null && operations.Count > 0)
      {
        this.CollectFormatOf(operations);
        this.DetermineFormatOf(operations);
        this.InformFormatOf(operations);
      }
    }

    public virtual void Log(int length)
    {
      this.Log(OperationFormat.of(length));
    }
    public virtual void Log(int branchingTo, int shortFormat, int longFormat)
    {
      this.Log(OperationFormat.of(branchingTo, shortFormat, longFormat));
    }

    protected virtual void Log(OperationFormat format)
    {
      this.FormatList.Add(format);
    }
    protected virtual void CollectFormatOf(List<SmilOperation> operationList)
    {
      if (operationList != null)
      {
        foreach (SmilOperation smil in operationList)
        {
          if (smil != null)
          {
            smil.LogFormatAt(this);
          }
        }
      }
    }
    protected virtual void DetermineFormatOf(List<SmilOperation> operationList)
    {
    }
    protected virtual void InformFormatOf(List<SmilOperation> operationList)
    {
      if (operationList != null)
      {
        for (int i = 0; i < operationList.Count; i++)
        {
          SmilOperation smil = operationList[i];
          if (smil != null)
          {
            smil.SetFormatAt(this, this.IsCurrentLongFormat(i));
          }
        }
      }
    }

    protected virtual bool? IsCurrentLongFormat(int index)
    {
      return (index >= 0 && index < this.FormatList.Count) ?
          this.FormatList[index].IsLongFormat :
          null;
    }

    #region Utils
    public virtual void Dispose()
    {
      this.Dispose(!this.isDisposed);
    }

    protected virtual void Dispose(bool disposing)
    {
      if (this.formatList != null)
      {
        this.formatList.Clear();
        this.formatList = null;
      }
    }
    #endregion
    #endregion
  }


}
